package me.zhyd.oauth.request;

import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.config.AuthDefaultSource;
import me.zhyd.oauth.enums.AuthUserGender;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.utils.BearerUtils;
import me.zhyd.oauth.utils.UrlBuilder;

/**
 * Boot登录,用户自定义
 */
public class AuthBootRequest extends AuthDefaultRequest {


	public AuthBootRequest(AuthConfig config) {
		super(config, AuthDefaultSource.BOOT);
	}

	public AuthBootRequest(AuthConfig config, AuthStateCache authStateCache) {
		super(config, AuthDefaultSource.BOOT, authStateCache);
	}

	@Override
	protected AuthToken getAccessToken(AuthCallback authCallback) {
		return this.getToken(accessTokenUrl(authCallback.getCode()));
	}

	/**
	 * 获取token，适用于获取access_token和刷新token
	 *
	 * @param accessTokenUrl 实际请求token的地址
	 * @return token对象
	 */
	private AuthToken getToken(String accessTokenUrl) {
		HttpResponse response = HttpRequest.get(accessTokenUrl).execute();
		JSONObject object = JSONObject.parseObject(response.body());
		if (object.getIntValue("code") != 0) {
			throw new AuthException(object.getString("message"));
		}
		JSONObject accessTokenObject = object.getJSONObject("data");
		System.out.println(response.body());
		return AuthToken.builder().accessToken(accessTokenObject.getString("value"))
				.refreshToken(accessTokenObject.getJSONObject("refreshToken").getString("value"))
				.expireIn(accessTokenObject.getIntValue("expiresIn")).build();
	}
	
	@Override
	protected AuthUser getUserInfo(AuthToken authToken) {
		String token = BearerUtils.buildBearerToken(authToken.getAccessToken());
		Map<String, String> headers = new HashMap<String, String>();
		headers.put("Authorization", token);
		String url= String.format(source.userInfo()+"?token=%s", BearerUtils.extracteToken(token));
		HttpResponse response = HttpRequest.get(url).addHeaders(headers)
				.execute();
		JSONObject object = JSON.parseObject(response.body());
		if (object.getIntValue("code") != 0) {
			throw new AuthException(object.getString("message"));
		}
		object = object.getJSONObject("data");
		return AuthUser.builder().uuid(object.getString("account")).nickname(object.getString("name"))
				.username(object.getString("name")).avatar(object.getString("headImageUrl"))
				.gender("W".equals(object.getString("gender")) ? AuthUserGender.FEMALE : AuthUserGender.MALE)
				.source(source.toString()).build();
	}

	/**
	 * 返回带{@code state}参数的授权url，授权回调时会带上这个{@code state}
	 *
	 * @param state state 验证授权流程的参数，可以防止csrf
	 * @return 返回授权地址
	 * @since 1.9.3
	 */
	@Override
	public String authorize(String state) {
		return UrlBuilder.fromBaseUrl(source.authorize()).queryParam("appId", config.getClientId())
				.queryParam("notifyUrl", config.getRedirectUri()).queryParam("additionalParam", getRealState(state))
				.build();
	}

}
